package com.jbp.service;

import com.jbp.exception.RRException;
import com.jbp.model.Gift;
import com.jbp.model.GiftLot;
import com.jbp.redis.RedisConfigService;
import com.jbp.service.impl.UserPropertyServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 呱呱 50块奖池 1：10
 */
@Service
public class LuckyUtil42 {
    @Autowired
    private RedisConfigService redisConfigService;

    @Autowired
    private LuckyUtil42Wool luckUtilBig;

    //每次抽消耗奖金币
    public static final int price = 500;

    @Autowired
    private UserPropertyServiceImpl userPropertyServiceImpl;
    /**
     * patch 补礼物  0表示不补
     * */
    public List<Gift> luck(Integer userId, int times, List<GiftLot> list, int patch, Integer roomId) {
        String keyUpay = "haoya:luck:"+price+":upay:"+userId;
        String keyUincmoe = "haoya:luck:"+price+":uincome:"+userId;
        String keyUTotalPay = "haoya:luck:"+price+":utotalpay:"+userId;
        String keyUTotalIncome = "haoya:luck:"+price+":utotalincome:"+userId;

        String keyPatchPool = "haoya:luck:patchpool";
        int patchPool = redisConfigService.getInt(keyPatchPool);
        patchPool += times * 0.02d * price;

        int pay = redisConfigService.getInt(keyUpay);
        int income = redisConfigService.getInt(keyUincmoe);
        int totalPay = redisConfigService.getInt(keyUTotalPay);
        int totalIncome = redisConfigService.getInt(keyUTotalIncome);
        int biggest = 500000;
        int maxGift = userPropertyServiceImpl.getMaxGift(userId);
        if (maxGift!=0) {
            biggest = maxGift;
        }
        //判断奖池
        if (totalPay+times*price<10000) {
            return luckUtilBig.luck(userId, times, list, 0, roomId);
        } else {
            List<Gift> result = new ArrayList<>();
            for (int i = 0; i < times; i++) {
                pay += price;
                totalPay += price;

                int luck = luck(pay, income, patch, biggest);
                if (luck>1000) {
                    patch++;
                }
                //将奖品转化为礼物
                Gift gift = null;
                for (GiftLot giftLot : list) {
                    if (giftLot.getGift().getCoin() == luck) {
                        gift = giftLot.getGift();
                        break;
                    }
                }

                if (gift==null) {
                    System.out.println("抽奖异常");
                    throw new RRException("网络错误");
                }

                income += gift.getCoin();
                totalIncome += gift.getCoin();
                result.add(gift);
            }

            redisConfigService.set(keyPatchPool, patchPool);
            redisConfigService.set(keyUpay, pay);
            redisConfigService.set(keyUincmoe, income);
            redisConfigService.set(keyUTotalPay, totalPay);
            redisConfigService.set(keyUTotalIncome, totalIncome);
            return result;
        }
    }


    Pool poolA = new Pool();
    Pool poolB = new Pool();
    Pool poolC = new Pool();
    Pool poolD = new Pool();
    @SuppressWarnings("AliControlFlowStatementWithoutBraces")
    void luckTest(UserLuck userLuck, Map <Integer, Integer> out) {
        if (userLuck.totalPay<10000) {
            new LuckyUtil42Wool().luckTest(userLuck, out);
        } else {
            Pool pl;
            if (userLuck.totalPay < 300000) {
                pl = poolB;
            } else if (userLuck.totalPay < 500000) {
                pl = poolC;
            } else {
                pl = poolD;
            }

            userLuck.pay += price;
            userLuck.totalPay += price;
            userLuck.currPay += price;
            pl.allPay += price;

            int luck = luck(userLuck.pay, userLuck.income, 0, 500000);

            userLuck.income += luck;
            userLuck.totalIncome += luck;
            userLuck.currIncome += luck;
            pl.allIncome += luck;
            pl.pool -= luck;

            if (out.containsKey(luck)) {
                out.put(luck, out.get(luck) + 1);
            } else {
                out.put(luck, 1);
            }
        }
    }

    private int luck(int pay, int income, int patch, int biggest) {
        LinkedHashMap<Integer, Integer> config;
        if (pay<300000) {
            config = getGiftCoinfigB();
        } else if (pay<500000) {
            config = getGiftCoinfigC();
        } else {
            config = getGiftCoinfigD();
        }
        int min=0;

        int maxWin;
        if (pay<30_0000) {
            maxWin = 25000;
        } else if (pay<100_0000) {
            maxWin = 25000;
        } else if (pay<300_0000) {
            maxWin = 20000;
        } else {
            maxWin = (int) (pay*(1.195-1.175));
        }

        biggest = Math.min(Math.max((int)(pay*1.177+maxWin-income), 15000), biggest);

        if (patch<1) {
            double pRate = 0;
            if (pay > 350000) {
                pRate = 1.018;
            } else if (pay > 320000) {
                pRate = 1.004;
            } else if (pay > 280000) {
                pRate = 0.97;
            } else if (pay > 150000) {
                pRate = 0.7;
            }

            if (pRate > 0 && pay * pRate > income) {
                if (pay > 500000) {
                    biggest = Math.min(biggest, 40000);
                    min = 5000;
                } else if (pay > 250000) {
                    biggest = Math.min(biggest, 20000);
                    min = 2000;
                } else if (pay > 100000) {
                    biggest = Math.min(biggest, 15000);
                    min = 1000;
                } else {
                    biggest = Math.min(biggest, 6000);
                    min = 100;
                }

            }

            min=Math.min(min, 20000);
            min = Math.min(min, biggest);

            /*if (min!=0) {
                System.out.println(min);
            }*/
        }

        return LuckyUtil.luckRandom(config, min, biggest);
    }

    /**
     * A奖池 投入1w钻以内
     */
    private static LinkedHashMap<Integer, Integer> getGiftCoinfigA() {
        LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();
        map.put(88, 1100);
        map.put(188, 650);
        map.put(288, 520);
        map.put(488, 500);
        map.put(888, 270);
        map.put(1888, 130);
        map.put(3388, 60);
        map.put(5188, 32);
        map.put(8888, 16);
        map.put(11888, 9);
        map.put(18888, 4);
        map.put(28888, 2);
        map.put(33888, 1);
        return map;
    }
    /**
     * B奖池 投入10w钻以内
     */
    private static LinkedHashMap<Integer, Integer> getGiftCoinfigB() {
        LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();
        map.put(88, 2000);
        map.put(188, 1300);
        map.put(288, 1000);
        map.put(488, 800);
        map.put(888, 500);
        map.put(1888, 150);
        map.put(3388, 90);
        map.put(5188, 52);
        map.put(8888, 20);
        map.put(11888, 9);
        map.put(18888, 5);
        map.put(28888, 2);
        map.put(33888, 2);
        map.put(68888, 1);
        return map;
    }

    /**
     * C奖池 投入50w钻以下
     */
    private static LinkedHashMap<Integer, Integer> getGiftCoinfigC() {
        LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();
        map.put(88, 1700);
        map.put(188, 1100);
        map.put(288, 800);
        map.put(488, 700);
        map.put(888, 400);
        map.put(1888, 100);
        map.put(3388, 65);
        map.put(5188, 32);
        map.put(8888, 18);
        map.put(11888, 8);
        map.put(18888, 4);
        map.put(28888, 2);
        map.put(33888, 2);
        map.put(68888, 1);
        return map;
    }

    /**
     * D奖池 投入50w钻以上
     */
    private static LinkedHashMap<Integer, Integer> getGiftCoinfigD() {
        LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();
        map.put(88, 1700);
        map.put(188, 1100);
        map.put(288, 800);
        map.put(488, 700);
        map.put(888, 450);
        map.put(1888, 120);
        map.put(3388, 70);
        map.put(5188, 40);
        map.put(8888, 20);
        map.put(11888, 12);
        map.put(18888, 8);
        map.put(28888, 3);
        map.put(33888, 3);
        map.put(68888, 2);
        map.put(88888, 1);
        return map;
    }


    public static void main(String[] args) {
        System.out.println("-------A-------");
        LuckyUtil.printConfig(getGiftCoinfigA(), price);
        System.out.println("-------B-------");
        LuckyUtil.printConfig(getGiftCoinfigB(), price);
        System.out.println("-------C-------");
        LuckyUtil.printConfig(getGiftCoinfigC(), price);
        System.out.println("-------D-------");
        LuckyUtil.printConfig(getGiftCoinfigD(), price);
        System.out.println("--------------");

        LuckyUtil42 luckyUtil = new LuckyUtil42();
        Map <Integer, Integer> result = new LinkedHashMap<>();
        List<UserLuck> userLucks = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            UserLuck user = new UserLuck();
            user.id=i;
            while (true) {
                luckyUtil.luckTest(user, result);
//                if (user.totalPay>=10000000 || (user.totalIncome*0.85d-user.totalPay>0)) {
                if (user.totalPay>=300_0000) {
                    double rate  = BigDecimal.valueOf(user.totalIncome).divide(BigDecimal.valueOf(user.totalPay), 4, BigDecimal.ROUND_HALF_UP).doubleValue();
                    System.out.println(i+": 投入："+user.totalPay+" 产出:"+user.totalIncome +"  爆率:"+rate+ " 实际盈利："+(int)(user.totalIncome*0.85d-user.totalPay));
                    break;
                }
            }
            userLucks.add(user);
        }
        LuckyUtil.printConfig(result, price);

        LuckyUtil.tjUser(userLucks);

        System.out.println("------------系统爆率------------");
        System.out.println("A 系统投入:"+luckyUtil.poolA.allPay+" 产出:"+luckyUtil.poolA.allIncome+" 总爆率:"+ ((double)luckyUtil.poolA.allIncome/luckyUtil.poolA.allPay)+" 奖池剩余："+luckyUtil.poolA.giftCount+" 剩余爆率:"+((double)luckyUtil.poolA.pool/price/luckyUtil.poolA.giftCount));
        System.out.println("B 系统投入:"+luckyUtil.poolB.allPay+" 产出:"+luckyUtil.poolB.allIncome+" 总爆率:"+ ((double)luckyUtil.poolB.allIncome/luckyUtil.poolB.allPay)+" 奖池剩余："+luckyUtil.poolB.giftCount+" 剩余爆率:"+((double)luckyUtil.poolB.pool/price/luckyUtil.poolB.giftCount));
        System.out.println("C 系统投入:"+luckyUtil.poolC.allPay+" 产出:"+luckyUtil.poolC.allIncome+" 总爆率:"+ ((double)luckyUtil.poolC.allIncome/luckyUtil.poolC.allPay)+" 奖池剩余："+luckyUtil.poolC.giftCount+" 剩余爆率:"+((double)luckyUtil.poolC.pool/price/luckyUtil.poolC.giftCount));
        System.out.println("D 系统投入:"+luckyUtil.poolD.allPay+" 产出:"+luckyUtil.poolD.allIncome+" 总爆率:"+ ((double)luckyUtil.poolD.allIncome/luckyUtil.poolD.allPay)+" 奖池剩余："+luckyUtil.poolD.giftCount+" 剩余爆率:"+((double)luckyUtil.poolD.pool/price/luckyUtil.poolD.giftCount));
        System.out.println("总 系统投入:"+(luckyUtil.poolA.allPay+luckyUtil.poolB.allPay+luckyUtil.poolC.allPay+luckyUtil.poolD.allPay)+
                " 产出:"+(luckyUtil.poolA.allIncome+luckyUtil.poolB.allIncome+luckyUtil.poolC.allIncome+luckyUtil.poolD.allIncome)+
                " 总爆率:"+ ((double)(luckyUtil.poolA.allIncome+luckyUtil.poolB.allIncome+luckyUtil.poolC.allIncome+luckyUtil.poolD.allIncome)/(luckyUtil.poolA.allPay+luckyUtil.poolB.allPay+luckyUtil.poolC.allPay+luckyUtil.poolD.allPay)));
    }
}

